package com.eden.config;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

import com.eden.util.TypeConvertUtil;

public class Configuration {

	private final Log log = LogFactory.getLog(Configuration.class) ;
	
	private boolean isShowOnStart ;
	private List<Score> scoreList ;
	private List<ScoreRange> scoreRangeList ;
	private Chart chart  ;
	private int total = 100 ;
	public  void config() {
		this.read("config/setup.xml") ;
	}

	
	@SuppressWarnings("unchecked")
	public void read(String fileName) {
		try {
			log.info("读取配置文件") ;
			FileInputStream fin = new FileInputStream(fileName) ;
			SAXReader reader = new SAXReader() ;
			Document document = null ;
			document = reader.read(fin) ;
			
			Element root = document.getRootElement() ;
			
			String isShowOnStartStr = (String) root.element("isShowOnStartup").getData() ;
			this.isShowOnStart = Boolean.valueOf(isShowOnStartStr) ;
			
			//图表的文字配置
			String data = null ;
			Element chartElement = root.element("chart") ;
			this.chart = new Chart();
			if(StringUtils.isNotBlank(data  = (String)chartElement.element("type").getData())){
				chart.setType(Integer.valueOf(data)) ;
			}
			if(StringUtils.isNotBlank(data  = (String)chartElement.element("title").getData())){
				chart.setTitle( data ) ;
			}
			if(StringUtils.isNotBlank(data  = (String)chartElement.element("x").getData())){
				chart.setxName( data ) ;
			}
			if(StringUtils.isNotBlank(data  = (String)chartElement.element("y").getData())){
				chart.setyName( data ) ;
			}
			
//			读取分数分布配置
			log.debug("读取分数分布") ;
			Element scores = root.element("scores") ;
			List<Element> scoreListElement = scores.elements("score") ;
			this.scoreList = new ArrayList<Score>() ;
			for(Element e: scoreListElement) {
				String name = (String) e.element("name").getData() ;
				String percent = (String)e.element("percent").getData() ;
				String validStr = (String)e.element("valid").getData() ;
				String isShowStr =  (String)e.element("isShow").getData();
				String isAnalyze = (String)e.element("isAnalyze").getData() ;
				
				Score score = new Score();
				score.setName(name) ;
				score.setPercent(Double.valueOf(percent)) ;
				boolean valid = Boolean.valueOf(validStr) ;
				boolean isShow = Boolean.valueOf(isShowStr) ;
				score.setShow(isShow) ;
				score.setValid(valid) ;
//				如果设置此列不在表中显示,则为无效(计算分数时,不参与计算)
				if(!isShow) {
					score.setValid(false) ;
				}
				score.setAnalyze(Boolean.valueOf(isAnalyze)) ;
				
				this.scoreList.add(score) ;
			}
			
			log.info("read score range configuration ") ;
			this.scoreRangeList = new ArrayList<ScoreRange>() ;
			Element range = root.element("range") ;
			List<Element> scoreRangeEleList = range.elements("entry") ;
			for(Element e : scoreRangeEleList) {
				ScoreRange sr = new ScoreRange() ;
				sr.setName(String.valueOf(e.element("name").getData())) ;
				sr.setMin(TypeConvertUtil.toDouble(e.element("min").getData())) ;
				sr.setMax(TypeConvertUtil.toDouble(e.element("max").getData())) ;
				this.scoreRangeList.add(sr) ;
			}
			log.info("read score range completed " + this.scoreRangeList ) ;
			
			//计算难序,区分度等时,用到的总分
			String totalStr = (String)root.element("total").getData() ;
			this.total = Integer.valueOf(totalStr) ;
			
			fin.close() ;
		} catch (FileNotFoundException e) {
			log.error(" config xml not found " + e) ;
		} catch (DocumentException e) {
			log.error("read config xml file error" + e) ;
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 持久化到配置文件
	 */
	public void persistent() {
		log.info("persistent configuration file") ;
		try {
			FileInputStream fin = new FileInputStream("config/setup.xml") ;
			SAXReader reader = new SAXReader() ;
			Document document = null ;
			document = reader.read(fin) ;
			
			Element root = document.getRootElement() ;
			
			//图表的文字配置
			String data = null ;
			Element chartElement = root.element("chart") ;
			chartElement.element("type").setText(TypeConvertUtil.toStr(chart.getType())) ;
			chartElement.element("title").setText(chart.getTitle()) ;
			chartElement.element("x").setText(chart.getxName()) ;
			chartElement.element("y").setText(chart.getyName()) ;
			
//			读取分数分布配置
			log.debug("persistent score distribution...") ;
			Element scores = root.element("scores") ;
			List<Element> scoreListElement = scores.elements("score") ;
			for(Element e: scoreListElement) {
				String name = (String) e.element("name").getData() ;
				for(Score score : scoreList) {
					if(StringUtils.equals(score.getName(), name)) {
						e.element("percent").setText(TypeConvertUtil.toStr(score.getPercent()) );
						e.element("valid").setText(TypeConvertUtil.toStr(score.isValid())) ;
						e.element("isShow").setText(TypeConvertUtil.toStr(score.isShow()));
						e.element("isAnalyze").setText(TypeConvertUtil.toStr(score.isAnalyze())) ;
					}
				}
			}
			
			XMLWriter writer = new XMLWriter(new FileOutputStream("config/setup.xml")) ;
			writer.write(document) ;
			writer.flush() ;
			writer.close() ;
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (DocumentException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public Configuration clone(){
		Configuration cf = new Configuration() ;
		return null ;
	}

	public boolean isShowOnStart() {
		return isShowOnStart;
	}


	public void setShowOnStart(boolean isShowOnStart) {
		this.isShowOnStart = isShowOnStart;
	}


	public List<Score> getScoreList() {
		return scoreList;
	}


	public void setScoreList(List<Score> scoreList) {
		this.scoreList = scoreList;
	}


	public Chart getChart() {
		return chart;
	}


	public void setChart(Chart chart) {
		this.chart = chart;
	}


	public int getTotal() {
		return this.total;
	}


	public void setTotal(int total) {
		this.total = total;
	}


	public List<ScoreRange> getScoreRangeList() {
		return scoreRangeList;
	}


	public void setScoreRangeList(List<ScoreRange> scoreRangeList) {
		this.scoreRangeList = scoreRangeList;
	}

}
